<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\VerifyCodeRequest;
use App\Models\Customer;
use App\Services\Api;
use App\Services\SmsSender;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class VerifyCodeController extends Controller
{
    protected $codeType = [
        'register' => SmsSender::USER_REGISTER,
        1 => SmsSender::USER_REGISTER,
        'login' => SmsSender::USER_LOGIN,
        2 => SmsSender::USER_LOGIN,
        'pwd_forget' => SmsSender::PASSWORD_FORGET,
        3 => SmsSender::PASSWORD_FORGET,
        'pwd_reset' => SmsSender::PASSWORD_RESET,
        4 => SmsSender::PASSWORD_RESET,
    ];

    /**
     * 发送验证码
     */
    public function index(Request $request, SmsSender $sender, $type)
    {
        $codeType = $this->codeType[$type] ?? null;

        if (!$codeType) {
            return Api::msg('api.verify_code.type_illegal');
        }

        if ($codeType === SmsSender::PASSWORD_RESET) {
            if (!Auth::user()) {
                return Api::msg('api.login.need');
            }
        }

        $mobile = $request->input('mobile');

        $user = Customer::query()->where('mobile', $mobile)->first();

        switch ($codeType) {
            case SmsSender::USER_REGISTER:
                if ($user) {
                    return Api::msg('api.user.exists');
                }
                break;
            default:
                if (!$user) {
                    return Api::msg('api.user.not_exists');
                }
                break;
        }

        $request->request->add(['type' => $codeType]);

        $key = Str::upper(md5($mobile . $codeType));

        $code = $this->getCode($key);

        if (envIsProduction() && !$sender->send($codeType, $mobile, $code)) {
            return Api::msg('api.verify_code.failure');
        }

        return Api::msg('api.verify_code.success', ['verify_key' => $key]);
    }

    protected function getCode($key)
    {
        $cache = Cache::get($key);

        if (!$cache) {
            $cache = [
                'code' => envIsProduction() ? rand(100000, 999999) : '1',
                'params' => request()->all()
            ];
            Cache::put($key, $cache, 5);
        }

        return $cache['code'];
    }

    /**
     * 验证验证码
     */
    public function verify(VerifyCodeRequest $request)
    {
        $key = $request->input('verify_key');

        $code = $request->input('verify_code');

        $cache = cache($key);

        if (!$cache) {
            return Api::msg('api.verify_code.expired');
        }

        if ($cache['code'] != $code) {
            return Api::msg('api.verify_code.check_failure');
        }

        cache()->forget($key);

        if ($cache['code'] === SmsSender::PASSWORD_RESET) {
            return Api::msg('api.verify_code.check_success');
        }

        $user = Customer::query()
            ->firstOrCreate(['mobile' => $cache['params']['mobile']]);

        $token = Api::token($user);

        if (is_null($user->verify_at)) {
            // 未设置密码, 需要去设置密码
            return Api::msg('api.password.empty', $token);
        }

        return Api::msg('api.verify_code.check_success', $token);
    }
}
